<?php
/**
 * In this file the class '\BF\TranslatorConfig' is defined.
 *
 * @author     Ulf Kadner <ulfikado@gmail.com>
 * @category   Beluga PHP5.3+ Framework
 * @copyright  (c) 2015, Ulfikado
 * @package    BF\Core
 * @since      2015-01-17 12:45
 * @version    0.1
 */

namespace BF
{

   /**
    * Defines all settings for creating a Translator instance.
    *
    * @since   v0.1
    */
   class TranslatorConfig
   {

      # <editor-fold defaultstate="collapsed" desc=" - - -   P U B L I C   F I E L D S   - - - - - - - - - - - - - - - - - - - - - - -">

      /**
       * This array contains all currently usable translation folders.
       *
       * You can define one or more folders that contain some localized translation data (translation folder)
       * The first folder is defined automatic and is used by Framework for internal translations. Don't remove it or
       * the framework does not use localized data.
       *
       * Each translation folder must follow a predefined structure:
       *
       * <pre>
       * [translation folder]
       *   |
       *   +- [de_DE]
       *   |    |
       *   |    +- namespace1.php
       *   |    +- namespace2.php
       *   |    +- …
       *   |
       *   +- [nl]
       *   |    |
       *   |    +- namespace1.php
       *   |    +- namespace2.php
       *   |    +- …
       *   +- […]
       * </pre>
       *
       * You have to define for every loacale a separate folder. If there is no need to specify translations for a
       * specific country/region you can only use the LID (Language ID) als folder name.
       *
       * For every locale you can define one or more namespaces as separate PHP files wich contains the translation for
       * a specific application range. If you use more namespace it reduces more the overhead of loaded data, because
       * the translation data are only loaded if they are needed.
       *
       * @var    array A directory path string array.
       * @since  v0.1
       */
      public $TransFolders = array();

      /**
       * Defines if the global Translator instance is enabled.
       *
       * @var    boolean
       * @since  v0.1
       */
      public $Enabled = true;

      # </editor-fold>

      # <editor-fold defaultstate="collapsed" desc=" - - >   P U B L I C   C O N S T R U C T O R   - - - - - - - - - - - - - - - - - -">

      /**
       * Init's a new instance.
       */
      public function __construct()
      {

         $this->TransFolders[] = \BF_FOLDER . '/-translations';

      }

      # </editor-fold>

      # <editor-fold defaultstate="collapsed" desc=" - - -   P U B L I C   M E T H O D S   - - - - - - - - - - - - - - - - - - - - - -">

      /**
       * Returns a array with all storeable values of the current instance.
       *
       * The returned array uses the keys 'Folders', 'Enabled'.
       *
       * @return array
       * @since  v0.1
       */
      public function toArray()
      {

         return array(
            'Folders' => $this->TransFolders,
            'Enabled' => $this->Enabled
         );

      }

      /**
       * Reinit's the instance data from the defined array, requires keys (caseless) are: 'Folders', 'Enabled'
       *
       * @param  array   $array
       * @return integer Returns how many array values are used.
       */
      public function fromArray( array $array )
      {

         // Make lower case array keys
         $array = \array_change_key_case( $array );

         // Counter of: How many array elements was handled
         $handled = 0;

         if ( \array_key_exists( 'folders', $array ) && \is_array( $array[ 'folders' ] ) )
         {
            // Handle the 'Folder' config property
            $this->TransFolders = $array[ 'folders' ];
            $handled++;
         }
         if ( \array_key_exists( 'enabled', $array ) )
         {
            // Handle the 'Enabled' config property
            $this->Enabled = \BF\FrameworkConfig::isBooleanTrue( $array[ 'enabled' ] );
            $handled++;
         }

         // Returns how many properties are reinitialized
         return $handled;

      }

      /**
       * Adds a existing Translation folder to the current list of translation folders.
       *
       * @param  string $folder The folder path to add
       * @return boolean Returns TRUE on success, FALSE if the folder don't exists, or if its already registered.
       */
      public function addTranslationFolder( $folder )
      {

         if ( \in_array( $folder, $this->TransFolders ) )
         {
            // If the source folder is always defined, return FALSE
            return false;
         }

         if ( ! \is_dir( $folder ) )
         {
            // If the folder is unusable (don't exists), return FALSE
            return false;
         }

         // Add it to TransFolders
         $this->TransFolders[] = $folder;

         // Success
         return true;

      }

      /**
       * Writes the current instance data to defined XML writer.
       *
       * The resulting XML looks like:
       *
       * <code>
       * &lt;TranslatorConfig enabled="1"&gt;
       *    &lt;Folders&gt;
       *       &lt;Folder&gt;…&lt;/Folder&gt;
       *       &lt;Folder&gt;…&lt;/Folder&gt;
       *    &lt;/Folders&gt;
       * &lt;/TranslatorConfig&gt;
       * </code>
       *
       * @param \XMLWriter $w           The XML writer
       * @param string     $elementName The name of the XML element that should contains the data (defaults to 'TranslatorConfig')
       */
      public function writeXml( \XMLWriter $w, $elementName = 'TranslatorConfig' )
      {

         // Writing <TranslatorConfig
         $w->startElement( $elementName );

         // Write enabled="1|0">
         $w->writeAttribute( 'enabled', $this->Enabled ? '1' : '0' );

         if ( \is_array( $this->TransFolders ) && \count( $this->TransFolders ) > 0 )
         {
            // The are folders defined that should be stored

            // Writing <Folders>
            $w->startElement( 'Folders' );

            foreach ( $this->TransFolders as $folder )
            {
               // Write each <Folder>…</Folder> element
               $w->writeElement( 'Folder', $folder );
            }

            // Writing </Folders>
            $w->endElement();
         }

         // Writing </TranslatorConfig>
         $w->endElement();

      }

      # </editor-fold>

      # <editor-fold defaultstate="collapsed" desc=" - - -   P U B L I C   S T A T I C   M E T H O D S   - - - - - - - - - - - - - - -">

      /**
       * Extracts a \BF\TranslatorConfig instance from a framework config XML element.
       *
       * @param  \SimpleXMLElement $fwConfigElement The XML root element of the whole BF framework config.
       * @param  string            $elementName     The name of the translator config XML element
       *                                            (default='TranslatorConfig')
       * @return \BF\TranslatorConfig Return the new \BF\TranslatorConfig instance, or boolean FALSE if no valid config
       *                              was found.
       */
      public static function FromXmlElement( \SimpleXMLElement $fwConfigElement, $elementName = 'TranslatorConfig' )
      {
         if ( ! isset( $fwConfigElement->{$elementName} ) )
         {
            return false;
         }
         $element = $fwConfigElement->{$elementName}[ 0 ];
         $enabled = \BF\XmlAttributeHelper::GetAttributeValue( $element, 'enabled', '0' ) === '1';
         $config = new \BF\TranslatorConfig();
         $config->Enabled = $enabled;
         if ( isset( $element->Folders ) && isset( $element->Folders->Folder ) )
         {
            $folders = array();
            foreach ( $element->Folders->Folder as $folder )
            {
               $dir = (string) $folder;
               if ( ! \is_dir( $dir ) )
               {
                  continue;
               }
               $folders[] = $dir;
            }
            if ( \count( $folders ) > 0 )
            {
               $config->TransFolders = $folders;
            }
         }
         return $config;
      }

      # </editor-fold>

   }

}

